//
//  ViewController.m
//  KVO
//
//  Created by jun on 2021/2/3.
//

#import "KVOViewController.h"
#import "KVOPerson.h"
#import <objc/runtime.h>
#import "NSObject+KVO.h"

@interface KVOViewController ()

@property KVOPerson *person;
@property KVOPerson *p1;

@end

@implementation KVOViewController

-(void)testClass{
    
    KVOPerson *p1 = KVOPerson.new;
    KVOPerson *p2 = KVOPerson.new;
    NSLog(@"p1：%p,p2:%p,Person:%p",p1,p2,[KVOPerson class]);
    
    p1.age= 1;
    p2.age = 2;

    //实现kvo
    NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
    [p1 addObserver:self forKeyPath:@"name" options:options context:nil];

    //p1和p2的方法和列表名发生了变化
    [self printMethods:object_getClass(p1)];
    [self printMethods:object_getClass(p2)];

    //但是指针没发生变化，说明kvo后指针发生了变化， 导致新类与就类的指针是一样的
    NSLog(@"p1：%p,p2:%p,Person:%p",p1,p2,[KVOPerson class]);
    
    //移除属性后赋值不奔溃，但是失败
    [self.p1 removeObserver:self forKeyPath:@"age"];
    self.p1.age = 18;
    NSLog(@"self.p1.age : %ld",self.p1.age);
    
    //删除监听后。触发kvo会闪退
//    [[NSNotificationCenter defaultCenter] removeObserver:p1 forKeyPath:@"age"];
//    NSLog(@"p1");
//    [self printMethods:object_getClass(p1)];
    NSLog(@"class : %@ + %@",[p1 class],[p2 class]);
    self.p1 = p1;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.view.backgroundColor = [UIColor whiteColor];

//    [self testClass];
    
    [self createKVO];
}

-(void)createKVO{
    self.person = KVOPerson.new;
    NSLog(@"self.person：%p,Person:%p",self.person,[KVOPerson class]);
    [self printMethods:object_getClass(self.person)];
    [self.person lg_addObserver:self forKeyPath:@"name"];
    self.person.name = @"ma";
    // 类名发生改变，KVOPerson=》KCKVO_KVOPerson
    [self printMethods:object_getClass(self.person)];
    NSLog(@"self.person：%p,Person:%p",self.person,[KVOPerson class]);
}

-(void)dealloc{
    NSLog(@"dealloc");
    //移除通知的时候，指针才会指回来:NSKVONotifying_KVOPerson=>KVOPerson
    if (self.person) {
        NSLog(@"self.person");
        [self printMethods:object_getClass(self.person)];
        [[NSNotificationCenter defaultCenter] removeObserver:self.person name:@"name" object:nil];
        
        [[NSNotificationCenter defaultCenter] removeObserver:self];
        [self printMethods:object_getClass(self.person)];
    }
    if (self.p1) {
        NSLog(@"self.p1");
        [self printMethods:object_getClass(self.p1)];
        [self.p1 removeObserver:self forKeyPath:@"name"];
        [self printMethods:object_getClass(self.p1)];
    }
    
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    NSLog(@"keyPath : %@\n change:%@ \n context:%@",keyPath,change,context);
}
 
#pragma mark - value 回调
- (void)lg_observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object newValue:(id)newValue{
    NSLog(@"keyPath : %@ \n object:%@ \n newValue:%@",keyPath,object,newValue);
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    self.person.name = [NSString stringWithFormat:@"%@+",self.person.name];
}

-(void)printMethods:(Class)cls{
    unsigned int count ;
    //获取方法列表
    Method *methods = class_copyMethodList(cls, &count);
    NSMutableString *methodNames = [NSMutableString string];
    [methodNames appendFormat:@"%@ - ",cls];
    
    for (int i =0 ; i<count; i++) {
        Method method = methods[i];
        NSString *methodName = NSStringFromSelector(method_getName(method));
        
        [methodNames appendString:methodName];
        [methodNames appendString:@" + "];
    }
    //添加kvo的p1 与没添加的p2的 类名和方法列表都不一样 》 kvo后类发生了变化
    NSLog(@"methodNames : %@",methodNames);
    free(methods);
}


@end
